/***************************************************************************************************
  *Copyright(C),2010-2016,Sumscope
  *FileName	:  StopCodec.cpp
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2019/09/11
  *Desc		:  //用于主要说明此程序文件完成的主要功能
  *Relation :  
  *Others	:  //其他内容说明
  *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
  *History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#include "StopCodec.h"
#include "TableCodec.h"
#include "common_util.h"
#include "BitView.h"
#include "BitViewWriter.h"
#include <cstdlib>
#include <map>
#include <core/Utility.h>

namespace qb{
	namespace proto{
		namespace{
			static const bool gs_use_variant_double = true;//是否使用浮点变长编码
			class TenMultiplyBase{
				i64		m_base[19];
			public:
				TenMultiplyBase(){
					m_base[0] = 1;
					for (int i = 1; i < _countof(m_base);i++)
					{
						m_base[i] = m_base[i - 1] * 10;
					}
				}
				inline i64 operator[](int index){ return m_base[index]; }
			};
			class TenDivisionBase{
				double		m_base[19];
			public:
				TenDivisionBase()
				{
					i64 num = 1;
					for (int i = 0; i < _countof(m_base); i++)
					{
						m_base[i] = 1.0 / num;
						num *= 10;
					}
				}
				inline double operator[](int index){ return m_base[index]; }
			};
			i64 GetTenMultiply(int width){
				static TenMultiplyBase base;
				return base[width];
			}
			double GetTenDivision(int width){
				static TenDivisionBase base;;
				return base[width];
			}
		}
		int VariantDouble::ParsePrecision(const char* buf, int len)
		{
			int nvalid = 0, nfill = 0, ndelta = 0, ntail = 0;
			kStepMode mode = kStepModeTail;
			char cfill = 0, cdelta = 0;

			for (int i = len - 1; i >= 0; i--)
			{
				char c = buf[i];
				if (c == '.')break;
				switch (mode)
				{
				case kStepModeTail:
					if (c == '0')
						ntail++;
					else
					{
						mode = kStepModeDelta;
						i++;
					}
					break;
				case kStepModeDelta:
					ndelta++;
					cdelta = c;
					mode = kStepModeFill;
					break;
				case kStepModeFill:
					if ((c == '0' || c == '9') && cfill == 0)
					{
						cfill = c;
						nfill = 1;
					}
					else if ((c == '0' || c == '9') && cfill == c)
						nfill++;
					else{
						mode = kStepModeValid;
						i++;
					}
					break;
				case kStepModeValid:
					nvalid++;
					break;
				}
			}
			if (nfill <= 0)
			{
				ndelta = 0;
				nvalid++;
			}
			int width = nvalid;
			if (nfill > 0){
				BASSERT(cfill == '0' || cfill == '9');
				if (nfill <= 4)
					width += nfill + 1;
				else if (cfill == '9')
					width++;
			}
			return width;
		}
		bool VariantDouble::ConvertDoubleEx(double d, i64& val, int& width)
		{
			char buf[64] = { 0 };
			int len = FMTBUF(buf, "%.15f", d);
			width = ParsePrecision(buf, len);
			double temp = d*GetTenMultiply(width);
			val = (i64)(temp + 0.5);	// round(temp);
			double result = val*GetTenDivision(width);
			return result == d;

		}
		bool VariantDouble::ConvertDouble(double d, i64& val, int& width)
		{
			// 性能测定,是ConvertDoubleEx时间的0.164倍
			// 假设绝大多数double精度只有1-6位
			for (int i = 1; i <= 6; i++)
			{
				i64 num =(i64)(d*GetTenMultiply(i) +0.5);//替换round
				double result = num*GetTenDivision(i);
				if (result == d)
				{
					val = num;
					width = i;
					return true;
				}
			}
			return ConvertDoubleEx(d, val, width);
		}
		bool VariantDouble::ConvertFloat(float f, int& val, int& width)
		{
			char buf[64] = { 0 };
			int len = FMTBUF(buf, "%.7f", f);
			width = ParsePrecision(buf, len);
			int multi = (int)GetTenMultiply(width);
			float temp = f*multi;
			val = (int)(temp+0.5);//round
			float result = (float) (val*GetTenDivision(width));
			return result == f;
		}
		int VariantDouble::EncodeFloat(unsigned char* buf, int capcity, float d)
		{
			const unsigned char bitflag = 1, bitint = 3, bitval = 3;
			const unsigned char bithead = bitflag + bitint;
			const unsigned char stopmask = (1 << ShiftDigit) - 1;//0x7F

			int width = 0, delta = 0;
			int num = 0;
			unsigned char flag = 0;
			unsigned int unum = 0;
			if (ConvertFloat(d, num, width))
			{
				unum = (unsigned int)StopCodec::ToZigzag(num);
				flag = ((unsigned char)(unum & ((1 << bitval) - 1))) << bithead;
				flag |= (unsigned char)(width << bitflag) | (unsigned char)0x01;
				unum = unum >> bitval;
			}
			else
			{
				unum = *((unsigned int*)&d);
				flag = ((unsigned char)(unum & 0x3F)) << bitflag;
				unum = unum >> (ShiftDigit - 1);
			}
			int pos = 0;
			buf[pos++] = flag;
			while (unum != 0)
			{
				buf[pos++] = (unsigned char)(unum & stopmask);
				unum = unum >> ShiftDigit;
			}
			buf[pos - 1] |= StatusEnd;
			return pos;
		}
		int VariantDouble::DecodeFloat(const unsigned  char* buf, int capcity, float& d)
		{
			const unsigned char bitflag = 1, bitint = 3, bitval = 3;
			const unsigned char bithead = bitflag + bitint;
			const unsigned char widthmask = ((1 << bitint) - 1) << bitflag;
			const unsigned char valmask = ((1 << bitval) - 1) << bithead;
			const unsigned char stopmask = (1 << ShiftDigit) - 1;
			const unsigned char flagmask = (1 << bitflag) - 1;

			unsigned int num = 0;
			int pos = 1, width = 0, shift = bitval;
			if (buf[0] & flagmask)
			{
				width = (buf[0] & widthmask) >> bitflag;
				num = (buf[0] & valmask) >> bithead;
			}
			else
			{
				num = (buf[0] & stopmask) >> bitflag;
				shift = ShiftDigit - bitflag;
			}
			if (!(buf[0] & StatusEnd))
			{
				for (; pos < capcity; pos++, shift += ShiftDigit)
				{
					num |= ((unsigned int)(buf[pos] & stopmask)) << shift;
					if (buf[pos] & StatusEnd)
					{
						pos++;
						break;
					}
				}
			}
			if (buf[0] & flagmask)
				d = (float) (StopCodec::FromZigzag(num)*GetTenDivision(width));
			else
				d = *((float*)&num);
			return pos;
		}
		int VariantDouble::Encode(unsigned char* buf, int capcity, double d)
		{
			const unsigned char bitflag = 1, bitint = 4, bitval = 2;
			const unsigned char bithead = bitflag + bitint;
			const unsigned char stopmask = (1 << ShiftDigit) - 1;//0x7F
			i64 num = 0;
			int width = 0, delta = 0;
			unsigned char flag = 0;
			ui64 unum = 0;
			if (ConvertDouble(d, num, width))
			{
				unum = StopCodec::ToZigzag(num);
				flag = ((unsigned char)(unum & ((1 << bitval) - 1))) << bithead;
				flag |= (unsigned char)(width << bitflag) | (unsigned char)0x01;
				unum = unum >> bitval;
			}
			else
			{
				unum = *((ui64*)&d);
				flag = ((unsigned char)(unum & 0x3F)) << bitflag;
				unum = unum >> (ShiftDigit - 1);
			}
			int pos = 0;
			buf[pos++] = flag;
			while (unum != 0)
			{
				buf[pos++] = (unsigned char)(unum & stopmask);
				unum = unum >> ShiftDigit;
			}
			buf[pos - 1] |= StatusEnd;
			return pos;
		}
		int VariantDouble::Decode(const unsigned  char* buf, int capcity, double& d)
		{
			const unsigned char bitflag = 1, bitint = 4, bitval = 2, bithead = 5;
			const unsigned char widthmask = ((1 << bitint) - 1) << bitflag;
			const unsigned char valmask = ((1 << bitval) - 1) << bithead;
			const unsigned char stopmask = (1 << ShiftDigit) - 1;
			const unsigned char flagmask = (1 << bitflag) - 1;

			ui64 num = 0;
			int pos = 1, width = 0, shift = bitval;
			if (buf[0] & flagmask)
			{
				width = (buf[0] & widthmask) >> bitflag;
				num = (buf[0] & valmask) >> bithead;
			}
			else
			{
				num = (buf[0] & stopmask) >> bitflag;
				shift = ShiftDigit - bitflag;
			}
			if (!(buf[0] & StatusEnd))
			{
				for (; pos < capcity; pos++, shift += ShiftDigit)
				{
					num |= ((ui64)(buf[pos] & stopmask)) << shift;
					if (buf[pos] & StatusEnd)
					{
						pos++;
						break;
					}
				}
			}
			if (buf[0] & flagmask)
				d = StopCodec::FromZigzag(num)*GetTenDivision(width);
			else
				d = *((double*)&num);
			return pos;
		}
		int VariantDouble::CalcSize(double d)
		{
			unsigned char buf[20] = { 0 };
			return Encode(buf, _countof(buf), d);
		}


		int TrimTailZero(const char * buf, int len)
		{
			// 移除浮点数字符串末尾小数点右边的0
			// 2015.000000 ==> 2015,返回4
			bool dot = false;
			int end = -1;
			for (int i = len - 1; i >= 0; i--)
			{
				if (buf[i] == '.')
				{
					dot = true;
					break;
				}
				if (buf[i] != '0' && end<0)
					end = i + 1;
			}
			return (dot && end>=0) ? end : len;
		}
		/*
			自定义ascii映射表 [0-9a-zA-Z\.\-]
		*/
		class AsciiMapTable{
		protected:
			std::vector<unsigned char> m_ascii_set;
			std::map<unsigned char, int> m_ascii_map;
		public:
			AsciiMapTable(){
				InitTable();
			}
			int FindV(unsigned char ch) {
				std::map<unsigned char, int>::iterator iter = m_ascii_map.find(ch);
				if (iter != m_ascii_map.end()) {
					return iter->second;
				}
				return -1;
			}
			bool FindC(size_t i, unsigned char& ch) {
				BASSERT(i >= 0 && m_ascii_set.size() > 0);
				if (i < m_ascii_set.size()) {
					ch = m_ascii_set[i];
					return true;
				}
				return false;
			}
		protected:
			void InitTable()
			{
				m_ascii_set.clear();
				m_ascii_map.clear();
				int nIndex = 0;
				for (unsigned char n = '-'; n <= 'z'; ++n)
				{
					if (!(n == '-' || n == '.' || (n >= '0' && n <= '9')
						|| (n >= 'A' && n <= 'Z') || (n >= 'a' && n <= 'z'))) continue;
					m_ascii_set.push_back(n);
					m_ascii_map[n] = nIndex++;
				}
			}

		};
		class AsciiMap{
		public:
			int FindV(unsigned char ch)
			{//编码:从[0-9\.\-a-zA-Z]到数字0-63
				//if (ch >= '0'&&ch <= '9')return ch - '0';
				//else if (ch >= 'a'&&ch <= 'z')return 12 + ch - 'a';
				//else if (ch >= 'A'&&ch <= 'Z')return 38 + ch - 'A';
				//else if (ch == '.')return 10;
				//else if (ch == '-')return 11;
				static int valArray[256] = {
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 10, -1,
					0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
					-1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
					53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1,
					-1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
					27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
					-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
				};
				return valArray[ch];
			}
			bool FindC(size_t i, unsigned char& ch) 
			{
				//数字0-63到[0-9\.\-a-zA-Z]
				static unsigned char chArray[64] = {
					'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-', 'a', 'b', 'c', 'd',
					'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
					'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
					'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
				};
				if (i < 64){ ch = chArray[i]; return true; }
				return false;
			}
		};
		static AsciiMap g_AsciiTable;

		inline bool IsAlphaNumber(const char* str,int len)
		{
			for (int i = 0; i < len; i++)
			{
				unsigned char uc = str[i];
				if ((uc >= 'a'&&uc <= 'z') ||
					(uc >= 'A'&&uc <= 'Z') ||
					(uc >= '0'&&uc <= '9') ||
					uc == '.' || uc == '-')
					continue;
				return false;
			}
			return true;
		}
		inline int BytesOfVarInt(ui64 nTmp)
		{
			// 计算一个正整数需要几个字节编码
			int bytesize = 0;
			while (true)
			{
				nTmp = ((ui64)nTmp) >> 7;
				++bytesize;
				if (nTmp == 0){
					break;
				}
			}
			return bytesize;
		}
		inline bool IsIntegerStr(const char* str, int len)
		{
			if (str == NULL || len <= 0 || len >= 20)
				return false;
			if (len == 1)
			{
				if (str[0] == '-')return false;//不能编码成整数
				if (str[0] == '0')return true;//可以编码成整数
			}

			// 排除0开头的整数
			int nstart = 0;
			int npos = (str[0] == '-')? 1: 0;
			for (int i = npos; i < len; i++)
			{
				unsigned char uc = str[i];
				if (uc<'0' || uc > '9' ||(uc == '0' && nstart <= 0))
					return false;
				if (uc > '0')
					nstart++;
			}
			return true;
		}
		inline bool IsNumberStr(const char* str, int len)
		{
			for (int i = 0; i < len; i++)
			{
				unsigned char uc = str[i];
				if ((uc >= '0'&&uc <= '9') ||
					uc == '.' || uc == '-')
					continue;
				return false;
			}
			return true;
		}
		/*
			将原始字符串流当成指定bit宽度的bit流,用于解码
		*/
		StopCodec::StopCodec(unsigned char* buf, int capcity,bool write):
			m_buffer(buf), m_capcity(capcity), m_pos(0), m_write(write)
		{
			// 期望capcity足够大
		}
		void StopCodec::Init(unsigned char* buf, int capcity, bool write)
		{
			m_buffer = buf;
			m_capcity = capcity;
			m_pos = 0;
			m_write = write;
		}
		int StopCodec::CalcEncodeSize(kEncodeType type, const VarValue& val)
		{
			// 计算类型val在编码type下的尺寸,字节数,用于根据收集到的值,推断出最佳编码类型
			// 如果不能编码,返回-1;
			// 考虑停止位编码后的尺寸
			// 如果考虑zigzag算法,还需要精确计算负数用zigzag编码后的尺寸
			// 默认值也需要计算正常编码大小
			switch (type)
			{
			case kEncodeTypeStrRaw: //8 bit
				if (val.type == kExpectTypeString)
				{
					int bitsize = val.str.len * 8;
					int bytesize = (bitsize + ShiftDigit - 1) / ShiftDigit;
					return bytesize;
				}
				break;
			case kEncodeTypeStrAlpNum://6bit
				if (val.type == kExpectTypeString && IsAlphaNumber(val.str.ptr, val.str.len))
				{
					int bitsize = val.str.len * 6;
					int bytesize = (bitsize + ShiftDigit - 1) / ShiftDigit;
					return bytesize;
				}break;
			case kEncodeTypeStrNum: //4bit
				if (val.type == kExpectTypeString && IsNumberStr(val.str.ptr, val.str.len))
				{
					int bitsize = val.str.len * 4;
					int bytesize = (bitsize + ShiftDigit - 1) / ShiftDigit;
					return bytesize;
				}
				else if (val.type == kExpectTypeDouble)
				{
					// 允许double类型编码成字符串,且截掉末尾0
					char buf[64] = { 0 };
					int len = FMTBUF(buf, ConvertPrecision::GetFormat(), val.d);
					len = TrimTailZero(buf, len);
					int bitsize = len * 4;
					int bytesize = (bitsize + ShiftDigit - 1) / ShiftDigit;
					return bytesize;
				}
				break;
			case kEncodeTypeVarInt:
				if (val.type == kExpectTypeInt)
				{
					return BytesOfVarInt(ToZigzag(val.i));
				}
				else if (val.type == kExpectTypeString && IsIntegerStr(val.str.ptr, val.str.len))
				{
					ui64 nTmp = ToZigzag(MathUtil::atoi(val.str.ptr));//_atoi64
					return BytesOfVarInt(nTmp);
				}
				break;
			case kEncodeTypeVarUint:
				if (val.type == kExpectTypeInt && val.i >= 0)
				{
					return BytesOfVarInt((ui64)val.i);
				}
				break;
			case kEncodeTypeDouble:
				if (val.type == kExpectTypeDouble)
				{
					if (gs_use_variant_double)
						return VariantDouble::CalcSize(val.d);
					else
						return BytesOfVarInt((ui64)val.i);
				}
				break;
			default:
				BASSERT(0);
				break;
			}
			return -1;
		}

		int StopCodec::AddValue(kEncodeType type, const VarValue& value)
		{
			// 将一个值以type编码方式添加到当前编码器中,并返回添加的字节长度
			// 如果value的类型不支持转化成type类型,那么断言,如kExpectTypeString到kEncodeTypeVarInt,可能就转不了
			BASSERT(m_write);
			BASSERT(type >= kEncodeTypeStrRaw && type <= kEncodeTypeFixedBit);
			switch (type){
			case kEncodeTypeStrRaw:
			{
				BASSERT(value.type == kExpectTypeString || value.type == kExpectTypeNull);
				return EncodeTypeStr(type, value, 8, false);
			}break;
			case kEncodeTypeStrAlpNum:
			{
				BASSERT(value.type == kExpectTypeString || value.type == kExpectTypeNull);
				return EncodeTypeStr(type, value, 6, true);
			}break;
			case kEncodeTypeStrNum:
			{
				BASSERT(value.type == kExpectTypeString || value.type == kExpectTypeNull||
					value.type==kExpectTypeDouble);
				if (value.type == kExpectTypeDouble)//double转化编码成字符串
				{
					char buf[64] = { 0 };
					int len = FMTBUF(buf, ConvertPrecision::GetFormat(), value.d);
					len = TrimTailZero(buf, len);
					return EncodeTypeStr(type, VarValue(buf,len), 4, true);
				}
				return EncodeTypeStr(type, value, 4, true);
			}break;
			case kEncodeTypeVarInt: //int 类型使用base-128变长编码
			{
				// 将字符串编码成整数的时候,自动转化
				if (value.type == kExpectTypeInt || value.type == kExpectTypeNull)
					return EncodeTypeVarInt(type, value);
				else if (value.type==kExpectTypeString)//字符串转化编码成int
					return EncodeTypeVarInt(type, VarValue(MathUtil::atoi(value.str.ptr)));//  _atoi64
				BASSERT(0);
			}break;
			case kEncodeTypeDouble://当做ui64来编码,解码的时候也按照ui64来读取
			{
				// 经过测试,全部double,通过转化的概率是83.71%
				BASSERT(value.type == kExpectTypeDouble || value.type == kExpectTypeNull);
				if (gs_use_variant_double)
				{
					int bytes = VariantDouble::Encode(m_buffer + m_pos, m_capcity - m_pos, value.d);
					m_pos += bytes;
					return bytes;
				}else
					return EncodeVarUint(value.u);
			}break;
			case kEncodeTypeVarUint:
			{
				if (value.IsDefault())
					return EncodeVarUint(0);
				else
				{
					BASSERT(value.type == kExpectTypeInt);
					return EncodeVarUint((ui64)value.i);
				}
			}break;
			case kEncodeTypeFixedBit:
				return 0;
			default:
				return 0;
			}
			return 0;
		}

		int StopCodec::EncodeVarUint(ui64 nTmp) {
			int pos = m_pos;
			while (true){
				m_buffer[m_pos++] = (unsigned char)((nTmp & 0x7F));
				nTmp = ((ui64)nTmp) >> 7;
				if (nTmp == 0) {
					m_buffer[m_pos - 1] = (unsigned char)((i64)m_buffer[m_pos - 1] | StatusEnd);
					break;
				}
			}
			return m_pos - pos;
		}
		int StopCodec::EncodeTypeVarInt(kEncodeType type, const VarValue& value) {
			BASSERT(type== kEncodeTypeVarInt);
			return EncodeVarUint(ToZigzag(value.i));
		}

		int StopCodec::EncodeTypeStr(kEncodeType type, const VarValue& value, int bitwidth, bool use_ascii_map)
		{
			class StackString{//替换std::string,提升性能
				enum{CAP=256};
				char		m_stack[CAP];
				char*		m_string;
				int			m_size;
			public:
				StackString(const char* str, int len):m_size(len){
					if (len >= CAP)m_string = new char[len + 1];
					else m_string = m_stack;
					if (str && len>0)
						memcpy(m_string, str, len);
				}
				~StackString(){ if (m_string != m_stack && m_string)delete[] m_string; }
				char& operator[](int index){ return m_string[index];}
				const char* c_str()const{ return m_string; }
				int size()const{ return m_size; }
			};
			BASSERT(type>=kEncodeTypeStrRaw && type<=kEncodeTypeStrNum);
			if (use_ascii_map) {
				StackString tmp((const char*)value.str.ptr, value.str.len);
				for (int i = 0; i < value.str.len; i++) {
					int v = g_AsciiTable.FindV(tmp[i]);
					BASSERT(v != -1);
					if (v == -1) {
						continue;
					}
					tmp[i] = v;
				}
				return EncodeBytes((const unsigned char*)tmp.c_str(), tmp.size(), bitwidth);
			}
			else {
				return EncodeBytes((const unsigned char*)value.str.ptr, value.str.len, bitwidth);
			}
		}

		int StopCodec::GetPos() const
		{
			// 返回当前编码的字节位置,开始是0
			return m_pos;
		}

		bool StopCodec::GetValue(kEncodeType type, VarValue& value, VarAllocator* allocator)
		{
			//从数据流中读取一个值,如果是字符串,调用allocator分配
			BASSERT(!m_write);
			BASSERT(type >= kEncodeTypeStrRaw && type <= kEncodeTypeFixedBit);

			switch (type){
			case kEncodeTypeStrRaw:
				return DecodeTypeStr(type, value, 8, allocator, false);
			case kEncodeTypeStrAlpNum:
				return DecodeTypeStr(type, value, 6, allocator, true);
			case kEncodeTypeStrNum:
				return DecodeTypeStr(type, value, 4, allocator, true);
			case kEncodeTypeVarInt://正负数
				return DecodeTypeVarInt(type, value);
			case kEncodeTypeVarUint://正整数,double
			{
				value.u = DecodeVarUint();
				value.type = kExpectTypeInt;
				return true;
				break;
			}
			case kEncodeTypeDouble:
			{
				if (gs_use_variant_double)
				{
					int bytes = VariantDouble::Decode(m_buffer + m_pos, m_capcity - m_pos, value.d);
					m_pos += bytes;
				}else
					value.u = DecodeVarUint();//直接更改编码,不能赋值
				value.type = kExpectTypeDouble;
				return true;
				break;
			}
			case kEncodeTypeFixedBit:
				return false;
			default:
				return false;
			}
		}
		ui64 StopCodec::DecodeVarUint()
		{
			ui64 nTmp = 0;
			for (int shift = 0; shift < sizeof(nTmp) * CHAR_BIT; shift += ShiftDigit)
			{
				if (m_buffer[m_pos] & StatusEnd)
				{
					nTmp |= (ui64)(m_buffer[m_pos] & 0x7F) << shift;
					++m_pos;
					break;
				}
				else{
					nTmp |= (ui64)(m_buffer[m_pos]) << shift;
					++m_pos;
				}
			}
			return nTmp;
		}
		bool StopCodec::DecodeTypeVarInt(kEncodeType type, VarValue& value) {
			BASSERT(type == kEncodeTypeVarInt);
			ui64 nTmp = DecodeVarUint();
			value.i = FromZigzag(nTmp);
			value.type = kExpectTypeInt;
			return true;
		}

		bool StopCodec::DecodeTypeStr(kEncodeType type, VarValue& value, int bitwidth, VarAllocator* allocator, bool use_ascii_map) {
			BASSERT(type >= kEncodeTypeStrRaw && type <= kEncodeTypeStrNum);

			int bytes = DecodeBytes(m_bytes, bitwidth);
			value = VarValue(allocator->AllocString("", m_bytes.size()), 0);

			for (size_t i = 0; i < m_bytes.size(); ++i) {
				unsigned char v = m_bytes[i];
				if (use_ascii_map) {
					bool ret = g_AsciiTable.FindC(v, v);
					BASSERT(ret);
					if (!ret) {
						continue;
					}
				}
				value.str.ptr[value.str.len] = (char)(v);
				value.str.len++;
			}
			value.type = kExpectTypeString;
			return true;
		}

		i64 StopCodec::GetInt(int failedValue)
		{
			//从数据流中读取一个整数
			BASSERT(!m_write);
			VarValue val((int)0);
			if (GetValue(kEncodeTypeVarInt, val, NULL))
				return val.i;
			return failedValue;
		}

		int StopCodec::EncodeBytes(const unsigned char* buf, int size, int bitwidth)
		{
			// 将原始字符串buf编码成停止位编码,bit宽度为bitWidth
			if (BitWriter::CalcBytes(size, bitwidth, true) + m_pos >= m_capcity)
				return -1;
			BitWriter view(m_buffer + m_pos, m_capcity - m_pos, size, bitwidth, true);
			for (int i = 0; i < size; i++){
				view.set(i, buf[i]);
			}
			m_pos += view.bytes();
			return view.bytes();
		}

		int StopCodec::DecodeBytes(std::vector<unsigned char>& buf, int bitWidth)
		{
			// 将按照停止位编码的内容解码成原始字符串buf,bit宽度为bitWidth
			int bytes = DecodeLength(m_buffer + m_pos, m_capcity - m_pos);
			BitView view(m_buffer + m_pos, bytes, bitWidth, true,true);
			int count = view.size();
			buf.reserve(count);
			buf.clear();
			for (int i = 0; i < count;i++)
			{
				buf.push_back(view.at(i));
			}
			m_pos += bytes;
			return bytes;
		}

	}//namespace base;
}//namespace ss;

